home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / bufferio.zip / BUFFERIO.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  7KB  |  263 lines

  1. UNIT BufferIO;
  2.  
  3. { BufferIO version 0.9: BETA!  This unit may or may not work.        }
  4. { This program is released into the public domain by its author (me) }
  5. { Bruce Feist.  }
  6.  
  7. { However, I respectfully request the following: }
  8.  
  9. {  If you redistribute it, please clearly indicate what changes you have }
  10. { made (if any).  Please don't delete or alter this notice, either.      }
  11. { And, please include all other materials that you received with it      }
  12. { (a documentation file and a driver program to test it).  Also, please  }
  13. { do NOT include any compiled code.  JUST include the .PAS files and     }
  14. { documentation.  That should make it harder to infect with any viruses! }
  15.  
  16. {   Anyway, please contact me, Bruce Feist, on Compuserve with any bug   }
  17. { reports, enhancement requests, or general suggestions.  My ID is       }
  18. { 71320,3635; you can reach me on the BPROGA forum.                      }
  19.  
  20. {   I hope this proves useful to you all.  }
  21.  
  22. {  ***************  }
  23.  
  24. {  BufferIO Unit Description }
  25. {  Purpose:                  }
  26.  
  27. {  This unit buffers reads done to any untyped file with a record length }
  28. { of 1.  The buffer size used is 9K.                                     }
  29.  
  30. {  Usage:  }
  31.  
  32. {  Just put a USES clause for the unit into any program or unit which     }
  33. { you want to buffer the reads on.  Make sure that ALL units referring to }
  34. { the file have the USES, otherwise you'll have problems.                 }
  35.  
  36. {  Compatability: }
  37.  
  38. {    BufferIO has been tested under TP 5.5.  It should work on all }
  39. { versions of TP from 4.0 up.                                      }
  40.  
  41. INTERFACE
  42.  
  43. USES DOS;
  44.  
  45. TYPE
  46.   TByteArray = ARRAY [0 .. MaxInt] OF byte;
  47.   PByteArray = ^TByteArray;
  48.  
  49.   TBuffFileRec =
  50.     RECORD
  51.       Handle: Word;
  52.       Mode:   Word;
  53.       RecSize: Word;
  54.       Private: ARRAY[1 .. 26] OF byte;
  55.       BufferPtr: PByteArray;
  56.       BufferPos: Word;
  57.       UsedBytes: Word;
  58.       BufferSize: Word;
  59.       ReqRecSize: Word;
  60.       Dirty: Boolean;
  61.       UserData: ARRAY [1 .. 3] OF byte;
  62.       Name: ARRAY[0 .. 79] OF char;
  63.     END;  { TBuffFileRec }
  64.  
  65.  
  66. PROCEDURE ReSet   (VAR FileID: FILE; OpenRecSize: Word);
  67. PROCEDURE ReWrite (VAR FileID: FILE; OpenRecSize: Word);
  68. PROCEDURE Close   (VAR FileID: FILE);
  69.  
  70. PROCEDURE BlockRead  (VAR FileID: FILE; VAR Buf; Count: Word; VAR Result: Word);
  71. PROCEDURE BlockWrite (VAR FileID: FILE; VAR Buf; Count: Word; VAR Result: Word);
  72. PROCEDURE Seek       (VAR FileID: FILE; n: longint);
  73. FUNCTION  FilePos    (VAR FileID: FILE): longint;
  74. FUNCTION  EOF         (VAR FileID: FILE): Boolean;
  75.  
  76.  
  77. IMPLEMENTATION
  78.  
  79. CONST
  80.   BuffSize = 9 * 1024;  { 1 diskette track }
  81.  
  82.  
  83. FUNCTION Min (x, y: word): word;
  84. BEGIN { min }
  85.   IF x > y
  86.     THEN Min := y
  87.     ELSE Min := x
  88. END;  { Min }
  89.  
  90.  
  91. PROCEDURE BFlush (VAR FileID: FILE);
  92. BEGIN { BFlush }
  93.   WITH TBuffFileRec(FileID) DO
  94.     BEGIN
  95.       Dirty := FALSE;
  96.     END;  { WITH }
  97. END;  { BFlush }
  98.  
  99.  
  100. PROCEDURE ReSet (VAR FileID: FILE; OpenRecSize: Word);
  101. BEGIN { ReSet }
  102.   System.ReSet (FileID, OpenRecSize);
  103.   IF OpenRecSize = 1 THEN
  104.     WITH TBuffFileRec(FileID) DO
  105.       BEGIN
  106.         Writeln ('Opened for buffered reading!');
  107.         GetMem (BufferPtr, BuffSize);
  108.         BufferSize := BuffSize;
  109.         UsedBytes := 0;
  110.         BufferPos := 0;
  111.         ReqRecSize := OpenRecSize;
  112.         Dirty := False;
  113.       END;  { WITH }
  114. END;  { ReSet }
  115.  
  116.  
  117. PROCEDURE ReWrite (VAR FileID: FILE; OpenRecSize: Word);
  118. BEGIN { ReWrite }
  119.   System.ReWrite (FileID, 1);
  120.   IF OpenRecSize = 1 THEN
  121.     WITH TBuffFileRec(FileID) DO
  122.       BEGIN
  123.         Writeln ('Opened for buffered writing!');
  124.         GetMem (BufferPtr, BuffSize);
  125.         BufferSize := BuffSize;
  126.         UsedBytes := 0;
  127.         BufferPos := 0;
  128.         ReqRecSize := OpenRecSize;
  129.         Dirty := False;
  130.       END;  { WITH }
  131. END;  { ReWrite }
  132.  
  133.  
  134. PROCEDURE Close (VAR FileID: FILE);
  135. BEGIN { Close }
  136.   IF TBuffFileRec (FileID).ReqRecSize = 1 THEN
  137.     BEGIN
  138.       BFlush (FileID);
  139.       WITH TBuffFileRec (FileID) DO
  140.         BEGIN
  141.           FreeMem (BufferPtr, BufferSize);
  142.           BufferSize := 0;
  143.           UsedBytes := 0;
  144.           BufferPos := 0;
  145.         END;  { WITH }
  146.     END;  { IF ReqRecSize }
  147.   System.Close (FileID);
  148. END;  { Close }
  149.  
  150.  
  151. PROCEDURE BlockRead (VAR FileID: FILE; VAR Buf; Count: Word; VAR Result: Word);
  152. CONST
  153.   FirstTime: Boolean = True;
  154. VAR
  155.   SoFar, BytesFromBuff, ReqBytes: Word;
  156.  
  157. BEGIN { BlockRead }
  158.   WITH TBuffFileRec(FileID) DO
  159.     IF ReqRecSize = 1 THEN
  160.       BEGIN
  161.         IF FirstTime THEN
  162.           BEGIN
  163.             Writeln ('First buffered read');
  164.             FirstTime := False;
  165.           END;
  166.         ReqBytes := count * ReqRecSize;
  167.         BytesFromBuff := min (ReqBytes, UsedBytes - BufferPos);
  168.         Move (BufferPtr^[BufferPos], Buf, BytesFromBuff);
  169.         Inc (BufferPos, BytesFromBuff);
  170.         SoFar := BytesFromBuff;
  171.         IF Dirty THEN
  172.           BEGIN
  173.             BFlush (FileID);
  174.           END;
  175.  
  176.         WHILE SoFar < ReqBytes DO
  177.           BEGIN
  178.             IF Dirty
  179.               THEN BFlush (FileID);
  180.             System.BlockRead (FileID, BufferPtr^, BufferSize, UsedBytes);
  181.             BytesFromBuff := min (ReqBytes - SoFar, UsedBytes);
  182.             Move (BufferPtr^, PByteArray(@Buf)^[SoFar], BytesFromBuff);
  183.             BufferPos := BytesFromBuff;
  184.             Inc (SoFar, BytesFromBuff);
  185.           END  { WHILE SoFar }
  186.       END  { IF ReqRecSize }
  187.     ELSE
  188.       System.BlockRead (FileID, Buf, Count, Result);
  189. END;  { BlockRead }
  190.  
  191.  
  192. PROCEDURE BlockWrite (VAR FileID: FILE; VAR Buf; Count: Word; VAR Result: Word);
  193. CONST
  194.   FirstTime: Boolean = True;
  195.  
  196. BEGIN { BlockWrite }
  197.   WITH TBuffFileRec (FileID) DO
  198.     IF ReqRecSize = 1 THEN
  199.       BEGIN
  200.         IF FirstTime THEN
  201.           BEGIN
  202.             Writeln ('First Buffered Write');
  203.             FirstTime := False;
  204.           END;
  205.         System.Seek (FileID, System.FilePos(FileID) + BufferPos);
  206.         System.BlockWrite (FileID, Buf, Count, Result);
  207.         TBuffFileRec(FileID).Dirty := True;
  208.         BufferPos := 0;
  209.         UsedBytes := 0;
  210.       END
  211.     ELSE
  212.       System.BlockWrite (FileID, Buf, Count, Result);
  213. END;  { BlockWrite }
  214.  
  215.  
  216. PROCEDURE Seek (VAR FileID: FILE; n: longint);
  217. BEGIN { Seek }
  218.   WITH TBuffFileRec (FileID) DO
  219.     IF ReqRecSize = 1 THEN
  220.       BEGIN
  221.         BFlush (FileID);
  222.         System.Seek (FileID, n);
  223.         BufferPos := 0;
  224.         UsedBytes := 0;
  225.       END
  226.     ELSE
  227.       System.Seek (FileID, n);
  228. END;  { Seek }
  229.  
  230.  
  231. FUNCTION FilePos (VAR FileID: FILE): longint;
  232. VAR
  233.   Result: Longint;
  234.  
  235. BEGIN { FilePos }
  236.   WITH TBuffFileRec (FileID) DO
  237.     IF ReqRecSize = 1 THEN
  238.       BEGIN
  239.         Result := System.FilePos (FileID)
  240.            - UsedBytes + TBuffFileRec(FileID).BufferPos;
  241.       END
  242.     ELSE
  243.       Result := System.FilePos (FileID);
  244.  
  245.   FilePos := Result;
  246. END;  { FilePos }
  247.  
  248.  
  249. FUNCTION EOF (VAR FileID: FILE): boolean;
  250. VAR
  251.   Result: Boolean;
  252. BEGIN { EOF }
  253.   WITH TBuffFileRec (FileID) DO
  254.     IF ReqRecSize = 1 THEN
  255.       Result := (BufferPos >= UsedBytes) AND System.EOF(FileID)
  256.     ELSE
  257.       Result := System.EOF(FileID);
  258.   EOF := Result;
  259. END;  { EOF }
  260.  
  261.  
  262. BEGIN { BufferIO }
  263. END.  { BufferIO }